﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace blackhouse.BlackApart.Data.Caching {
    public class CachedPricesDataAccess : IPricesDataAccess {

        #region Fields

        private IPricesDataAccess decoratedDataAccess;
        private NemoCache cache;

        #endregion

        #region Constructors

        public CachedPricesDataAccess(IPricesDataAccess decoratedDataAccess, string connectionStringToDecoretedDb) {
            this.decoratedDataAccess = decoratedDataAccess;
            this.cache = new NemoCache(TimeSpan.FromMinutes(2), connectionStringToDecoretedDb);
        }

        #endregion

        #region Methods

        public PriceRabatData[] GetPriceRabats(string language, int apartmentTypeId) {
            cache.Reset();
            cache.SetDependencyTables("T190");
            cache.SetKey("GetPriceRabats");
            cache.SetParameters(language, apartmentTypeId);
            PriceRabatData[] data = cache.GetData<PriceRabatData[]>();
            if (data == null) {
                data = this.decoratedDataAccess.GetPriceRabats(language, apartmentTypeId);
                cache.SetCaching(data);
            }
            return data;
        }

        public ApartmentPriceData[] GetPriceModifiers(int apartmentId) {
            cache.Reset();
            cache.SetDependencyTables("T28_T63", "T63", "T60", "T57", "T28_T78", "T78", "T28_T83", "T83", "T28_T88", "T88");
            cache.SetKey("GetPriceModifiers");
            cache.SetParameters(apartmentId);
            ApartmentPriceData[] data = cache.GetData<ApartmentPriceData[]>();
            if (data == null) {
                data = this.decoratedDataAccess.GetPriceModifiers(apartmentId);
                cache.SetCaching(data);
            }
            return data;
        }

        public double GetApartmentPrice(int apartmentId) {
            cache.Reset();
            cache.SetDependencyTables("T28");
            cache.SetParameters(apartmentId);
            cache.SetKey("GetApartmentPrice");
            double data = cache.GetData<double>();
            if (data == 0) {
                data = this.decoratedDataAccess.GetApartmentPrice(apartmentId);
                cache.SetCaching(data);
            }
            return data;
        }

        public VariantLineData[] GetPriceProfileVariants(int apartmentId) {
            cache.Reset();
            cache.SetDependencyTables("T19", "T28");
            cache.SetKey("GetPriceProfileVariants");
            cache.SetParameters(apartmentId);
            VariantLineData[] data = cache.GetData<VariantLineData[]>();
            if (data == null) {
                data = this.decoratedDataAccess.GetPriceProfileVariants(apartmentId);
                cache.SetCaching(data);
            }
            return data;
        }

        public DateModificationData[] GetPriceProfileDateModification(int apartmentId) {
            cache.Reset();
            cache.SetDependencyTables("T19", "T28");
            cache.SetKey("GetPriceProfileDateModification");
            cache.SetParameters(apartmentId);
            DateModificationData[] data = cache.GetData<DateModificationData[]>();
            if (data == null) {
                data = this.decoratedDataAccess.GetPriceProfileDateModification(apartmentId);
                cache.SetCaching(data);
            }
            return data;
        }

        public LengthOfStayModificationData[] GetPriceProfileLengthOfStayModification(int apartmentId) {
            cache.Reset();
            cache.SetDependencyTables("T19", "T28");
            cache.SetKey("GetPriceProfileLengthOfStayModification");
            cache.SetParameters(apartmentId);
            LengthOfStayModificationData[] data = cache.GetData<LengthOfStayModificationData[]>();
            if (data == null) {
                data = this.decoratedDataAccess.GetPriceProfileLengthOfStayModification(apartmentId);
                cache.SetCaching(data);
            }
            return data;
        }

        public ApartmentPrice GetApartmentDbPrice(DateTime startDate, DateTime endDate, int apartmentId, int peopleCount) {
            cache.Reset();
            cache.SetDependencyTables("T19", "T28", "T190", "T197", "T201", "T207");
            cache.SetKey("GetApartmentDbPrice");
            cache.SetParameters(startDate, endDate, apartmentId, peopleCount);
            ApartmentPrice data = cache.GetData<ApartmentPrice>();
            if (data.DayCount == 0) {
                data = this.decoratedDataAccess.GetApartmentDbPrice(startDate, endDate, apartmentId, peopleCount);
                cache.SetCaching(data);
            }
            return data;
        }

        #endregion

    }
}
